// OGoMojo
// Whitemice.MOGI.ZOGI.Server
// License: LGPL
// Copyright: Whitemice Consulting, 2006
// Author(s): Adam Tauno Williams (awilliam@whitemice.org)
using System;
using System.Net;
using System.Web;
using System.Collections;
using Whitemice.MOGI;
using CookComputing.XmlRpc;

namespace Whitemice.MOGI.ZOGI
{	
	public class Server : Whitemice.MOGI.AsyncServer, Whitemice.MOGI.IAsyncServer
	{	
		protected Whitemice.MOGI.ZOGI.zOGI	protocol;
		
		public Server(string logName) : base (logName)
		{
			protocol = new Whitemice.MOGI.ZOGI.zOGI(this);
		}
		
		internal void SetCurrentActor(IAccount account)
		{
			this.currentActor = account;
		}
		
		public override NetworkCredential Credentials 
		{
			get 
			{
				return credentials;
			}
			set 
			{
				credentials = value;
				protocol.Credentials = credentials;
			}
		}
		
		public override string Hostname
		{
			get
			{
				return hostname;
			}
			set
			{
				hostname = value;
				protocol.Hostname = hostname;
			}
		}
				
		protected override void FillSupportedOperations()		
		{
			((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.Get);
			//((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.Put);
			((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.Fetch);
			//((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.Remove);
			((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.XA);
			//((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.AccessCheck);
			//((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.AccessGrant);
			((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.ListRelations);
			((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.ObjectLinkList);
			//((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.MakeRelation);
			((ArrayList)supportedOperations[DocumentType.Contact]).Add(Operation.GetFavorites);
			((ArrayList)supportedOperations[DocumentType.Enterprise]).Add(Operation.Get);
			((ArrayList)supportedOperations[DocumentType.Enterprise]).Add(Operation.Fetch);
			((ArrayList)supportedOperations[DocumentType.Enterprise]).Add(Operation.XA);
			((ArrayList)supportedOperations[DocumentType.Enterprise]).Add(Operation.GetFavorites);
			((ArrayList)supportedOperations[DocumentType.Enterprise]).Add(Operation.ListRelations);
			((ArrayList)supportedOperations[DocumentType.Enterprise]).Add(Operation.ObjectLinkList);
			((ArrayList)supportedOperations[DocumentType.Project]).Add(Operation.Get);
			((ArrayList)supportedOperations[DocumentType.Project]).Add(Operation.Fetch);
			((ArrayList)supportedOperations[DocumentType.Project]).Add(Operation.GetFavorites);
			((ArrayList)supportedOperations[DocumentType.Project]).Add(Operation.ListRelations);
			((ArrayList)supportedOperations[DocumentType.Project]).Add(Operation.ObjectLinkList);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.Fetch);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.Get);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.ReadAnnotations);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.ReadAudit);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.MakeAnnotation);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.GetAnnotation);
			((ArrayList)supportedOperations[DocumentType.Task]).Add(Operation.ListRelations);
			((ArrayList)supportedOperations[DocumentType.Team]).Add(Operation.Get);
			((ArrayList)supportedOperations[DocumentType.Team]).Add(Operation.ReadAudit);
			((ArrayList)supportedOperations[DocumentType.Team]).Add(Operation.ListRelations);
			((ArrayList)supportedOperations[DocumentType.Team]).Add(Operation.ObjectLinkList);			
			((ArrayList)supportedOperations[DocumentType.Undefined]).Add(Operation.GetName);
		}
		
		public override bool Connected
		{
			get { return protocol.Connected; }
		}
		
		protected override IMOGIObject ServerGet(string name)
		{
			return protocol.GetObjectByName(name, true);
		}
		
		protected IMOGIObject UncachedServerGet(string name)
		{
			return protocol.GetObjectByName(name, false);
		}
		
		protected override ArrayList ServerSearch(DocumentType documentType, 
																							string[] criteria, int max)
		{
			if (criteria[0] == "Favorites")
				return protocol.GetFavorites(documentType);
			return null;
		}
		
		protected override void ServerAsyncSearch(DocumentType documentType, 
																							string[] criteria,
		                                          AsyncSearchCallback callback, 
		                                          object context)
		{
			Console.WriteLine("ServerAsyncSearch");
			if(criteria[0] == "Favorites")
				protocol.AsyncGetFavorites(documentType, callback, context);
			switch(documentType)
			{
				case DocumentType.Task:
						Console.WriteLine("ServerAsyncSearch:DocumentType.Task");
						if (criteria[0].Split('=')[0] == "list")
						{
							Console.WriteLine("ServerAsyncSearch:DocumentType.Task:List={0}",
								criteria[0].Split('=')[1]);
							protocol.AsyncGetTaskList(criteria[0].Split('=')[1], callback, context);
						}
					break;
			}
		}
		
		protected override void ServerAsyncGet(string documentName, AsyncSearchCallback callback, object context)
		{
			protocol.AsyncGetObject(Convert.ToInt32(MOGI.Id(documentName)), callback, context);
		}
		
		protected override IAnnotation TaskAnnotation(string documentId) 
		{ 
			return (IAnnotation)protocol.GetObjectByName(documentId);
		}
		
		protected ArrayList GetFavorites(DocumentType documentType, int max)
		{
			return null;
		}
		
		/// \brief Get the server's name for a primary key
		/// \parap objectId 
		protected override string ServerGetName(string objectId)
		{
			return protocol.GetName(objectId);
		}
		
		protected override ArrayList GetTaskAnnotations(string documentId)
		{
			return protocol.GetTaskAnnotations(documentId); 
		}

    protected override void PutTaskAnnotation(ITaskAnnotation document)
    {
    	Log.Debug("MakeTaskAnnotation(documentId=" + MOGI.Id(document.Document) + ")");
    	int result;
    	
     	switch(document.Action)
      {
        case ETaskStatus.Accepted:
          Log.Debug("MakeTaskAnnotation(document=" + document.Document + ") - Accepted");
					result = protocol.PutTaskNotation(MOGI.Id(document.Name), "accept", document.Comment);
          break;
        case ETaskStatus.Rejected:
          Log.Debug("MakeTaskAnnotation(document=" + document.Document + ") - Rejected");
					result = protocol.PutTaskNotation(MOGI.Id(document.Name), "reject", document.Comment);
          break;
     		case ETaskStatus.Done:
          Log.Debug("MakeTaskAnnotation(document=" + document.Document + ") - Done");
					result = protocol.PutTaskNotation(MOGI.Id(document.Name), "done", document.Comment);
          break;
    		case ETaskStatus.Archived:
          Log.Debug("MakeTaskAnnotation(document=" + document.Document + ") - Archived");
					result = protocol.PutTaskNotation(MOGI.Id(document.Name), "archive", document.Comment);
          break;
        default:
          Log.Debug("MakeTaskAnnotation(document=" + document.Document + ") - Default");                                                
					result = protocol.PutTaskNotation(MOGI.Id(document.Name), "comment", document.Comment);
          break;
      }
      Log.Debug("MakeTaskAnnotation(document=" + document.Document + ") resulted in " + result.ToString());
      if (result == 1)
      	UncachedServerGet(document.Name);      
		}
		
		protected override ArrayList ServerAudit(string documentId) 
		{ 
			return protocol.GetDocumentAudit(documentId);
		}
		
		protected ArrayList GetGenericRelations(string documentId)
		{
			ArrayList relations;
			
			relations = new ArrayList();
			foreach(IRelation relation in protocol.GetObjectLinks(documentId))
				relations.Add(relation);
			return relations;			
		}
		
		protected override ArrayList GetAccountRelations(string documentId) 
		{ return GetGenericRelations(documentId); }

		protected override ArrayList GetAppointmentRelations(string documentId) 
		{ return GetGenericRelations(documentId); }
		
		protected override ArrayList GetContactRelations(string documentId) 
		{ return GetGenericRelations(documentId); }
		
		protected override ArrayList GetEnterpriseRelations(string documentId) 
		{ return GetGenericRelations(documentId); }
		
		protected override ArrayList GetProjectRelations(string documentId) 
		{ return GetGenericRelations(documentId); }
		
		protected override ArrayList GetResourceRelations(string documentId) 
		{ return GetGenericRelations(documentId); }
		
		protected override ArrayList GetTaskRelations(string documentId) 
		{
			ArrayList relations;
			IRelation	project;
			
			Console.WriteLine("Server::GetTaskRelations(" + documentId + ")");
			relations = GetGenericRelations(documentId);
			// Add project relation if one is related
			project = protocol.GetProjectForTask(documentId);
			if(project != null)
				relations.Add(project);
			return relations;
		}
		
		protected override ArrayList GetTeamRelations(string documentId) 
		{ return GetGenericRelations(documentId); }
	}
}
